<?php
namespace control;

//管理员后台-入库单
class inStockClass extends adIndexClass
{
    private const title       = '待入库单';
    private const page        = 'inStock';
    private const table       = 'inventory';
    private const tableMx     = 'inventory_detail';
    private const tableRecord = 'inventory_record';
    private const workflow    = ['待入库', '部分入库', '已入库'];
    private const source      = ['生产入库', '生产退料', '委外收货','委外退料', '销售退货', '采购收货', '线边库存退库', '报废入库'];
    private const qualityState  = ['无', '待质检', '已质检'];

    /**
     * 字段初始化
     */
    public function fieldInit($fun): array
    {

        switch ($fun) {
            default:
                $tr = [
                    'warehouse'          => [
                        'name'  => '{l.inStock.homeForm.warehouse}',
                        'width' => 200,
                    ],
                    'type' => [
                        'name'  => '{l.inStock.homeForm.source}',
                        'width' => 200,
                    ],
                    'sourceNo'  => [
                        'name'  => '{l.inStock.homeForm.sOrderNo}',
                        'width' => 300,
                        'sort' => 1,
                    ],
                    'targetId'  => [
                        'name'  => '{l.inStock.homeForm.targetId}',
                        'width' => 200,
                    ],
                    'sourceDate'  => [
                        'name'  => '{l.inStock.homeForm.sDate}',
                        'width' => 200,
                        'sort' => 1,
                    ],
                    'orderNo'         => [
                        'name'  => '{l.inStock.homeForm.orderNo}',
                        'width' => 200,
                        'sort' => 1,
                    ],
                    'state'          => [
                        'name'  => '{l.inStock.homeForm.stateSelect}',
                        'width' => 200,
                    ],
                    'oddNum'          => [
                        'name'  => '{l.inStock.detail.oddNum}',
                        'width' => 200,
                    ]
                ];
        }
        return $tr;
    }

    /*列表页-查询条件*/
    public function homeOptions($isAsync = true)
    {
        $result = sqlFind(" SELECT id, name FROM `warehouse` WHERE coid = '" . self::$coid . "' AND state = '启用' " . self::getWarehouseSql());
        $value  = [];
        foreach ($result as $key => $v) {
            $value[$v['id']] = $v['name'];
        }
        //生成查询表单
        $html = $this->tableShow([
            [
                [
                    L('inStock.homeForm.warehouse') => checkbox([
                        "name"    => "warehouse",
                        "value"   => $value,
                        'checked' => '',
                    ]),
                ],
                [
                    L('inStock.homeForm.source') => select(["name" => "source", 'option' => self::source]),
                    L('inStock.homeForm.orderNo')   => text(array("name" => "orderNo")),
                    L('inStock.homeForm.sOrderNo')   => text(array("name" => "sOrderNo")),
                ],
                [
                    '往来单位'  => text(array('name' => 'sourceTargetName',"title" => '往来单位', 'id' => 'target')) .
                        hidden(array('name' => 'targetId')).
                        <<<eof
                            <script>
                            $("#target").bigAutocomplete({
                                    url:root + 'control/adIndex.html?cla=inStockExec&fun=getTarget',
                                    callback:function(data){
                                        $("[name='targetId']").val(data.id);
                                    }
                                });
                            </script>
                        eof,
                    L('inStock.homeForm.sDate') => text(['name' => 'sDate', 'laydate' => ['range' => '~', 'type' => 'date'],]),
                    L('inStock.homeForm.stateSelect') => select(["name" => "deliver_on_schedule", 'option' => [1 => '是', 0 => '否']]),
                ],
                [
                    "状态" => select(["name" => "stateSelect", 'option' => self::workflow]).
                        hidden(['name' => 'state', 'value' => '待入库']),
                ]
            ]
        ],1);
        //返回
        if (!$isAsync) {
            return $html;
        } else {
            return json_encode(['html' => $html], 320);
        }
    }

    /**
     * 查询条件
     *
     * @return string
     */
    public function home(): string
    {
        $html = $this->homeOptions(false);
        //控件
        $button = "";
        if ($this->power(self::page, "export")) {
            $button .="<span class='spanButton' onclick=\"layer('importTemplate','exportFrame',{cla:'".self::page."',type:'待入库',classify:'待入库'})\">导出</span>";
        }
        $tip = componentClass::tipComponent('批量入库需要选择相同业务类型和相同往来单位的单据，如果入库前需要先完成质检，则数据无法带出', '!');
        $button .= <<<EOT
					<span class="spanButton" onclick="batchPutInStock()">批量入库</span>$tip
				EOT;
        $button .= "
					<script>
                        function batchPutInStock() {
                            var list = $(\"[name='listId[]']:checked\")
                            const arrar = []
                            if(list.length  == 0) {
                                warn('请选择待入库单')
                            }else{
                                list.each(function () {
                                    arrar.push($(this).val())
                                })
                                const url = root + 'control/adIndex.html?cla=inStock&fun=batchPutIn'
                                $.post(url, {ids:JSON.stringify(arrar)}, function (data) {
                                    if (data.warn == 2) {
                                        newIframe('" . L('inStockExec.homeListSearch.detail') . "',data.href)
                                    } else {
                                        warn(data.warn);
                                    }
                                }, 'json');
                            }
                        }
                    </script>
				";
        return $this->homeFun($this->search($html, layout: 'pop', toolButton: $button));
    }

    /*列表页-查询结果*/
    public function homeSearch($workFlow = '待入库')
    {
        $notIn  = ['其他入库', '调拨单入库', '拆解单入库', '组装单入库'];
        $where  = " `coid` = '" . self::$coid . "' AND `classify`=1  ";
        $equal = [
            'sourceTable' => match ($this->post('source')) {
                '盘点单'   => 'inventory_take',
                '采购退货'     => 'purchase_refund_order',
                '生产退料'     => 'pick_order',
                '销售退货'     => 'sale_refund_order',
                '采购收货'     => 'purchase_get_order',
                '生产入库'     => 'machining_in_order',
                '线边库存退库' => 'line_inventory_refund',
                '报废入库'     => 'scrapped_order',
                default        => '',
            },
        ];
        $like  = [
            'targetId' => $this->post('targetId'),
            'orderNo'  => $this->post('orderNo'),
            'sourceNo' => $this->post('sOrderNo'),
        ];
        $where .= self::timeComparison($this->post('sDate'), 'date', 'sourceDate');
        //生成查询语句
        $where .= search([
            "="    => $equal,
            "like" => $like,
        ]);
        if ($this->post('stateSelect')) {
            $where .= " and state = '" . $this->post('stateSelect') . "' ";
        } else {
            $where .= " and state in ('待入库','部分入库') ";
        }
        if ($this->post('warehouse')) {
            $where .= " AND warehouseId in ('" . implode("','", $this->post('warehouse')) . "')";
        } else {
            $where .= self::getWarehouseSql('warehouseId');  //自己管理的仓库
        }
        //排序
        $orderBy = $this->listSort(array(
            "search"  => $this->post('list_sort_key') ?: 'time',
            "sort" => $this->post('list_sort') ?: "desc",
            "array"   => array(),
        ));
        $page                                   = $this->page(["table" => self::table, "where" => $where, "order" => $orderBy['orderBy']]);
        $_SESSION[self::page][$workFlow]['sql'] = $page['sql'];
        $isPrint  = $this->power(self::page, "print");
        //获取自定义字段参数
        $installSearch = $this->installSearch();
        $body          = [];
        //表格控件区
        $liButton = array(
            $this->checkAll("listForm", "listId")
        );
        //获取记录
        $url = root . "control/adIndex.html?cla=" . self::page;
        //获取记录
        foreach ($page['array'] as $array) {
            //列表控件
            $dominate  = [
                "box"    => [
                    "name" => "listId", "value" => $array['id'],
                ],
                "detail" => [
                    "title" => L('inStock.homeSearch.detail'), "click" => "newIframe('" . L('inStock.homeSearch.detail') . "','" . $url . "&fun=detail&id=" . $array['id'] . "')",
                ],
            ];
            $liButton[] = $this->dominate($dominate);
            //本行初始化
            $row = [];
            foreach ($installSearch['key'] as $key) {
                switch ($key) {
                    case 'warehouse':
                        $warehouse = query('warehouse', " id = '$array[warehouseId]' ","name");
                        $row[] = $warehouse['name'];
                        break;
                    case 'targetId':
                        $row[] = inStockOtherClass::getCompanyName($array['targetId']);
                        break;
                    case 'sourceDate':
                        $row[] = self::formatDate($array['sourceDate']);
                        break;
                    case 'oddNum':
                        $oddNum = query(self::tableMx,"orderId = '$array[id]'",'sum(orderNum-num) as oddNum');
                        $row[] = $oddNum['oddNum'];
                        break;
                    default:
                        $row[] = isset($array[$key]) && $array[$key] ? $array[$key] : '';
                }
            }
            $body[] = $row;
        }
        //控件
        $button = "";
        //生成页面
        $li = $this->li(array(
            "body" => $body,
            "install" => $installSearch,
            "button" => array("html" => $liButton),
            "orderBySign" => $orderBy,
            "page" => $page['para'],
        ));
        //返回
        $json['html'] = $page['hint'] . $button . "<form name='listForm'>" . $li . "</form>" . $page['button'];
        return json_encode($json, 320);
    }

    /*详情页*/
    public function detail(): string
    {
        $info = query(self::table, " coid = '" . self::$coid . "' AND id = '{$this->get('id')}'");
        if (empty($info['id'])) {
            $html = L('inStock.detail.empty');
        } else {
            //菜单
            $data   = array(
                "id" => $info['id'],
            );
            $button = [];
            $button[] = [
                "name" => L('inStock.detail.print'),
                "type" => "弹出层",
                "cla"  => $this->get('cla'),
                "fun"  => "printEdit",
                "post" => ["id" => $info['id']],
            ];
            $sourceAlias = match ($info['sourceTable']) {
                'inventory_take'        => L('inStock.detail.check'),
                'pick_order'            => L('inStock.detail.pickReturn'),
                'purchase_refund_order' => L('inStock.detail.purchaseReturn'),
                'purchase_get_order'    => L('inStock.detail.purchaseGet'),
                'sale_refund_order'     => L('inStock.detail.saleReturn'),
                'machining_in_order'    => L('inStock.detail.productionIn'),
                'line_inventory_refund' => L('inStock.detail.sideInventory'),
                'scrapped_order'        => L('inStock.detail.ScrapReceipt'),
                default                 => L('inStock.detail.other'),
            };
            $warehouse   = query('warehouse', " id = '$info[warehouseId]' ");
            if ($info['sourceTable']) {
                $obj = query($info['sourceTable'], " id = '{$info['sourceId']}' ");
            } else {
                $obj['orderNo'] = $obj['text'] = $obj['recordDate'] = '';
            }
            $checkAll = $this->checkAll("detailForm", "listId");
            $mxtr[]   = [$checkAll, '{l.inStock.detail.code}', '{l.inStock.detail.name}', '{l.inStock.detail.model}', '{l.inStock.detail.unit}', '{l.inStock.detail.orderNum}', '{l.inStock.detail.putInNum}', '{l.inStock.detail.batchMx}', '{l.inStock.detail.oddNum}', '质检状态'];
            $result   = find(array('table' => self::tableMx, 'where' => "orderId = '$info[id]' order by list"));
            $totalArr = ['orderNum'=>0,'num'=>0];

            $inStockQuality = optionSettingClass::getSettingItem('库存', 'inStockQuality');// 入库前是否需要先完成质检
            foreach ($result['array'] as $array) {
                //列表控件
                $dominate    = [
                    "box" => [
                        "name" => "listId", "value" => $array['id'],
                    ],
                ];
                // 如果需要质检才能入库
                if($array['quality'] == 1 && $inStockQuality){
                    unset($dominate['box']);
                }
                $material    = query('material', " id = '$array[materialId]'");
                $batch  = self::getInventoryBatch($array['id']);  //查询批次对应数量
                $mxtr[] = [
                    $this->dominate($dominate),
                    $material['code'],
                    $material['name'],
                    $material['model'],
                    $array['unit'],
                    self::lostZero($array['orderNum'], 'numPrecision'),
                    self::lostZero($array['num'], 'numPrecision'),
                    $batch,
                    self::lostZero($array['orderNum'] - $array['num'], 'numPrecision'),
                    self::qualityState[$array['quality']]
                ];
                $totalArr['orderNum'] += $array['orderNum'];
                $totalArr['num'] += $array['num'];
            }
            $total_tr = [
                5 => self::lostZero($totalArr['orderNum'], 'numPrecision'),
                6 => self::lostZero($totalArr['num'], 'numPrecision'),
                8 => self::formattingFigure($totalArr['orderNum'] - $totalArr['num'], 'numPrecision'),
            ];
            $mxButton = '';
            if (in_array($info['state'], ['待入库', '部分入库'])) {
                $tip = $inStockQuality ? componentClass::tipComponent("入库前需要先完成质检，如果状态为待质检，则不能选择入库") : '';
                $mxButton .= <<<EOT
					<span class="smallButton" onclick="batchPutInStock('{$info['id']}')">批量入库</span>$tip
				EOT;
                $mxButton .= "
					<script>
                        function batchPutInStock(targetId) {
                            var list = $(\"[name='listId[]']:checked\")
                            var str = ''
                            const arrar = []
                            if(list.length  == 0) {
                                warn('请选择物料')
                            }else{
                                list.each(function () {
                                    arrar.push($(this).val())
                                })
                                str = arrar.join('/')
                                newIframe('" . L('inStockExec.homeListSearch.detail') . "',root +'control/adIndex.html?cla=inStockExec&fun=edit&targetId='+targetId+'&ids='+str)
                            }
                        }
                    </script>
				";
            }
            //生成表单
            $data['button'] = $this->tableShowButton($button);
            $data['html'] = $this->tableShow([
                [
                    [
                        L('inStock.detail.source') => $sourceAlias,
                        L('inStock.detail.sOrderNo') => $obj['orderNo'],
                        L('inStock.detail.targetId') => inStockOtherClass::getCompanyName($info['targetId']),
                        L('inStock.detail.sDate') => self::formatDate($obj['recordDate'] ?? ''),
                    ],
                    [
                        L('inStock.detail.text') => $obj['text'],
                        L('inStock.detail.orderNo') => $info['orderNo'],
                        L('inStock.detail.warehouse')     => $warehouse['name'],
                        L('inStock.detail.state')     => $info['state'],
                    ],
                    [
                        L('inStock.detail.startTime') => $info['commitTime'],
                        L('inStock.detail.completionDate') => $info['confirmTime'],
                        L('inStock.detail.storekeeper')       => componentClass::showSelector($warehouse['selector']),
                    ],
                ]
            ]);
            $data['html'] .= $this->detailList([
                'title' => L('inStock.detail.receiptDetails'),
                'button' => $mxButton,
                'html' => "<form name='detailForm'>".$this->listTable(array('tr' => $mxtr, 'showEmpty' => true, 'showSort' => true, 'total' => $total_tr))."</form>",
            ]);
            //生成页面
            $html = $this->tab($data);
        }
        //返回
        return $html;
    }

    // 批量入库组合
    public function batchPutIn()
    {
        $ids    = $this->post('ids') ? json_decode($_POST['ids'],true) : [];
        $first = [];
        $mxId = [];
        foreach ($ids as $k=>$id){
            $info = query(self::table, " coid = '" . self::$coid . "' AND id = '{$id}'");
            if($k===0)$first = $info;
            if($first['targetId'] == $info['targetId'] && $first['type'] == $info['type'] && $info['state'] != '已入库'){
                $result   = find(array('table' => self::tableMx, 'field' => 'id', 'where' => "orderId = '$info[id]' order by list"));
                $mxId = array_merge($mxId,array_column($result['array'],'id'));
            }
        }
        if(count($mxId) > 0) {
            $json['warn'] = 2;
            $json['href'] = root.'control/adIndex.html?cla=inStockExec&fun=edit&targetId='.$first['id'].'&ids='.implode('/',$mxId);
        }else{
            $json['warn'] = '未匹配到数据';
        }
        return json_encode($json, 320);
    }

    /** 显示对应批次数量
     *
     * @param string $inventoryMxId 出入库明细id
     * @param bool   $showPosition  是否显示仓位
     * @return string
     */
    public static function getInventoryBatch(string $inventoryMxId, bool $showPosition = false): string
    {
        $result = find(array('table' => 'inventory_record', 'where' => "inventoryMxId = '$inventoryMxId' and moveId = '' order by batch"));
        $html   = '';
        foreach ($result['array'] as $array) {
            if ($showPosition) {
                $warehouse_position = query("warehouse_position", " id = '" . $array['positionId'] . "' ", 'name');
                $position           = $warehouse_position['name'] . '，';
            } else {
                $position = "";
            }
            $html .= (static::isNull($array['batch']) ? '--' : $array['batch']) . '，' . $position . self::lostZero($array['num'], 'numPrecision') . '；<br/>';
        }
        return $html;
    }

    // 操作中转
    public function operate()
    {
        $act    = $this->post('act') ?? '';
        $id     = $this->post('id') ?? '';
        $pwd    = $word = $height = false; // 需要密码
        $form   = $power = '';
        $append = [];
        switch ($act) {
            case 'batchIn':
                $act      = 'edit';
                $msg      = '批量入库';
                $title    = '是否确认将选中的入库单明细批量入库';
                $function = 'batchInEdit';
                $word     = true;
                $form     = self::page . 'OperateForm, detailForm';
                break;
        }
        if (!$this->power(self::page, $act)) {
            $_SESSION['warn'] = '你还没有' . $msg . '的权限';
            $json             = [
                'warn' => 2,
                'href' => root . 'control/adIndex.html?cla=' . $this->get('cla') . '&fun=home',
            ];
        } else {
            return $this->confirm([
                'title'    => $title,
                'function' => $function,
                'form'     => $form,
                'power'    => $power,
                'pwd'      => $pwd,
                'word'     => $word,
                'append'   => $append,
                'height'   => $height,
            ]);
        }

        resp:
        return json_encode($json, 320);
    }

    /** 生成入库批次
     *
     * @param string $type     入库类型
     * @param string $targetId 入库对象
     * @return string
     */
    public static function getBatchNo(string $type, string $targetId = ''): string
    {
        switch ($type) {
            case '生产入库':
            case '生产退料':
                $product_line = query("product_line", " id = '" . $targetId . "' ");
                $prefix       = date("Ymd") . $product_line['orderNo'];
                break;
            case '采购收货':
            case '委外收货':
            case '其他入库':
                $supplier = query("supplier", " id = '" . $targetId . "' ");
                $code     = empty($supplier['code']) ? '000' : $supplier['code'];
                $prefix   = date("Ymd") . $code;
                break;
            default:
                $prefix = date("Ymd") . '000';
                break;
        }
        return codeTemplateClass::generateCode('batchDetail', [
            'prefix' => $prefix,
            'table'  => 'inventory_record',
            'field'  => 'batch',
            'where'  => " and coid = '" . self::$coid . "' ",
        ], []);
    }

    /**
     * 入库记录
     */
    public function putInRecord()
    {
        $id     = $this->post('id');
        $result = find(['table' => 'auditing_follow', 'where' => "typeId = '$id' AND type = '入库单' order by time desc"]);
        $list   = '';
        if (empty($result['array'])) {
            $list .= '<div class="record">暂无入库记录</div>';
        } else {
            foreach ($result['array'] as $array) {
                $list .= "<div class='record'>{$array['text']}&emsp;{$array['time']}</div>";
            }
        }
        $html = $list;
        return $this->layer(["title" => "编辑", "height" => 335, "width" => 750, "html" => $html]);
    }

    /** 批次相同情况数量汇总处理
     *
     * @param array $batch 批次数组
     * @param array $num   数量数组
     * @return array
     */
    public static function batchArrangement(array $batch, array $num): array
    {
        $arr = [];
        foreach ((array)$batch as $k => $v) {
            if (!array_key_exists($v, $arr)) {
                $arr[$v] = $num[$k];
            } else {
                $arr[$v] += $num[$k];
            }
        }
        return $arr;
    }


    /** 计算物料容差数量
     *
     * @param string $type       入库类型
     * @param string $materialId 物料ID
     * @param float  $num        参考数量
     * @return float
     */
    public static function toleranceNum(string $type, string $materialId, float $num): float
    {
        $material = query("material", " id = '$materialId' ");
        switch ($type) {
            case '生产入库':
            case '生产退料':
                $tolerance = $material['machiningTolerance'];
                break;
            case '采购收货':
                $tolerance = $material['buyTolerance'];
                break;
            case '委外收货':
                $tolerance = $material['outTolerance'];
                break;
            default:
                $tolerance = 0;
                break;
        }
        $num = self::formattingFigure($num * ($tolerance), 'numPrecision'); //容差数量
        return $num;
    }

    /** 检查入库的具体规格物料是否已存在相同批号
     *
     * @param string $materialId 物料id
     * @param array  $batch         批次
     * @return bool|mixed|string
     */
    public static function batchCheck(string $materialId, array $batch): mixed
    {
        $warn = true;
        /* 暂时取消批号重复限制，限制主要控制生产日期的问题，如果重复则取同一批号的第一次入库日期作为生产日期
         * foreach ((array)$batch as $k => $v) {
            $inventory_record = query("inventory_record", " coid = '".self::$coid."' and materialId = '$materialId' and batch = '$v' and num > 0 ", 'id,materialId');
            if (!empty($inventory_record['id']) && !empty($v)) {
                $material     = query("material", " id = '" . $inventory_record['materialId'] . "' ", 'name');
                $warn         = '批号【' . $v . '】已被【' . $material['name'] . '】使用过了';
                break;
            }
        }*/
        return $warn;
    }

    /**
     * 关闭生产计划单
     */
    public function closeMachiningOrder($mxId)
    {
        $detail = query(self::tableMx, "id = '$mxId'");
        if ($detail['sourceTable'] == 'machining_in_order_detail') {
            $flag = true;//生产计划中产品是否已全部入库
            //生产入库单明细
            $machining_in_order_detail = query('machining_in_order_detail', "id= '$detail[sourceId]'");
            //生产计划单产品
            $machining_order_product = query('machining_order_mx', "id = '$machining_in_order_detail[sourceId]'");
            //生产计划
            $machining_order = query('machining_order', "id = '$machining_order_product[orderId]'");
            $all             = find(array('table' => 'machining_order_mx', 'where' => "orderId = '$machining_order[id]' order by list asc"));
            foreach ($all['array'] as $item) {
                //已入库此生产计划单的总数量
                $inNum = 0;
                $all   = find(array('table' => self::tableMx, 'where' => "sourceId in (select id from machining_in_order_detail where sourceId = '$item[id]')"));
                foreach ($all['array'] as $array) {
                    $material    = query('material', "id = '$array[materialId]'");
                    $inNum       += machiningOrderClass::material_num_change($material['id'], $array['unit'], $material['unit'], $array['num']);
                }
                //此生产计划单的数量
                $material    = query('material', "id = '$item[materialId]'");
                $num         = machiningOrderClass::material_num_change($material['id'], $item['unit'], $material['unit'], $item['num']);
                if ($inNum < $num) {
                    $flag = !$flag;
                    break;
                }
            }
            if ($flag) {
                update(array(
                    'table' => 'machining_order',
                    'field' => [
                        'isClose' => 1,
                    ],
                    'where' => "id = '$machining_order[id]'",
                ));
            }
        }
    }

    /** 入库容差范围检查
     *
     * @param array $info
     * @return mixed
     */
    public static function inStockCheck(array $info): mixed
    {
        $result = find(array('table' => self::tableMx, 'where' => " orderId = '$info[id]' order by list asc "));
        $warn   = true;
        foreach ((array)$result['array'] as $array) {
            $tolerance = self::toleranceNum($info['type'], $array['materialId'], $array['orderNum']);  //入库容差数
            if ($array['num'] < $array['orderNum'] - $tolerance || $array['num'] > $array['orderNum'] + $tolerance) {
                $material = query("material", " id = '" . $array['materialId'] . "' ");
                $warn     = str_replace(['{{materialName}}'], [$material['name']], lang('inStock.inStockCheck.warn'));
                break;
            }
        }
        return $warn;
    }


    /**
     * 导出
     */
    public function exportData()
    {
        $workFlow = $this->get('type');
        $templateId = $this->get('templateId');
        $checkedId = $this->get('checkedId')?explode(',',$this->get('checkedId')):[];
        if (!$this->power(self::page, 'export')) {
            $_SESSION['warn'] = '你还没有导出的权限';
        } else {
            $data = [];
            $sql    = $_SESSION[self::page][$workFlow]['sql'];
            /***********标题**********/
            $title =[];
            $tempFieldAll = importTemplateClass::templateField(self::page, 'exportFieldInit', id:$templateId);
            foreach ($tempFieldAll as $array) {
                if ($array['display']){
                    $title[] = $array['aliasName'];
                }
            }
            //判断是否选中导出
            if (!self::is_null_array($checkedId)){
                $result = find(array(
                    "table" => self::table,
                    "where" => "id in ('".implode("','", $checkedId)."') order by time desc",
                ))['array'];
            }else{
                $result   = sqlFind($sql);
            }
            //导出数据生成
            foreach ($result as $array){
                $warehouse = query('warehouse', " id = '$array[warehouseId]' ");
                if ($array['sourceTable']) {
                    $obj = query($array['sourceTable'], " id = '{$array['sourceId']}' ");
                } else {
                    $obj['orderNo'] = '';
                }
                $mx   = find(array('table' => self::tableMx, 'where' => "orderId = '$array[id]' order by list"));
                foreach ($mx['array'] as $value) {
                    $column = [];
                    $material    = query('material', " id = '$value[materialId]'");
                    $batch  = self::getInventoryBatch($value['id']);  //查询批次对应数量
                    foreach ($tempFieldAll as $templateField){
                        if ($templateField['display']){
                            $column[] = match ($templateField['columnName']){
                                '仓库'=>$warehouse['name'],
                                '业务类型'=>$array['type'],
                                '源单编号'=>$obj['orderNo'],
                                '往来单位'=>inStockOtherClass::getCompanyName($array['targetId']),
                                '源单日期'=>self::formatDate($array['time']),
                                '入库单号'=>$array['orderNo'],
                                '物料编码'=>$material['code'],
                                '物料名称'=> $material['name'],
                                '规格型号'=> $material['model'],
                                '单位'=> $value['unit'],
                                '单据数量'=> self::lostZero($value['orderNum'], 'numPrecision'),
                                '已入库数量'=> self::lostZero($value['num'], 'numPrecision'),
                                '批次明细'=>$batch,
                                '剩余未入库数量'=>self::lostZero($value['orderNum'] - $value['num'], 'numPrecision'),
                                default=>'',
                            };
                        }
                    }
                    $data[] = $column;
                }
            }
            $text = str_replace(['{{staffName}}'], [$this->control['name']], lang('inStock.exportData.log'));
            $this->logText(["type" => self::page, "text" => $text]);
            $this->excelOut($title, $data, lang('inStock.exportData.title') . '-' . $workFlow . ".xlsx");
            exit(0);
        }
        header("Location:" . getenv("HTTP_REFERER"));
    }

    public function printEdit(): bool|string
    {
        $root    = root;
        $result  = find([
            'table' => self::tableMx,
            'where' => " orderId = '{$this->post('id')}' ",
        ]);
        $content = '';
        foreach ((array)$result['array'] as $array) {
            //材料信息
            $material     = query('material', "id = '$array[materialId]'");
            $barcode      = $material['barcode'];
            $parameter    = urlencode($barcode);
            $printNum = L('inStock.print.num');
            $print = L('inStock.print.print');
            $content      .= <<<EOT
                            <li>
                               <div class="qr-content">
                                     <img alt="" src='{$root}pay/wxpay/wxScanPng.php?url=$parameter'>
                                     <div class="qr-content-barcode">$barcode</div>
                                     <div class="qr-content-bottom">{$material['name']},{$material['model']}</div>
                                     <input name='listId[]' type='hidden' value='{$material['id']}'>
                               </div>
                               <input class="text qr-num" name='num[]' placeholder='{$printNum}'>
                           </li>
EOT;
        }

        $html = <<<EOT
                <form name="printForm" target="_blank" method="post" action="{$root}control/adIndex.html?cla=materialDetail&fun=printPage">
                <div class="printEditPage">
                      <ul>
                           $content
                      </ul>
                </div>
                <div style='width: 100%;margin-top: 40px;text-align: center;'>
                    <input type='submit' class='button' value='{$print}' ">
                </div>
                </form>

EOT;
        return $this->layer(array("title" => $print, "height" => 650, "width" => 900, "html" => $html . self::style(), "button" => false));
    }

    /**
     * 样式
     */
    public static function style(): string
    {
        return <<<EOT
<style>
.printEditPage{width: 100%;height: 500px;overflow: auto;}
.printEditPage>ul>li{float: left;margin: 5px;padding: 5px}
.qr-content{width: 240px;height: 180px;background-color: #F0F8FA;text-align: center;margin: 10px;padding: 10px;overflow: auto}
.qr-content img{width: 120px}
.qr-content-barcode{font-size: 15px;font-weight: bold;margin: 5px 0}
.qr-content-bottom{word-break:hyphenate;word-wrap:break-word;}
.qr-num{width: 250px;margin: 10px}
</style>
EOT;
    }

    /**
     * 批量打印
     *
     * @return string
     */
    public function batchPrint(): string
    {
        $lists = $this->get('lists');
        if(empty($lists)){
            exit('参数错误');
        }else{
            $listId = base64_decode($lists, true);
            $array = explode(',', $listId);
            $data = [];
            foreach ($array as $id){
                $data[] = static::printPage($id, false);
            }
            return (new printTemplateClass())->start(self::page, $data);
        }
    }

    /**
     * 打印
     *
     * @return string
     */
    public function printPage($param = '', $isReturn = true): string|array
    {
        $id                  = $param ?: $this->get('id');
        $info                = query(self::table, " id = '$id'");
        $info['companyName'] = query('company', "coid = '" . self::$coid . "'")['name']; //公司名称//公司名称
        $info['title']       = self::title;
        $info['printTime']   = $this->time;
        $info['stid']        = self::findStaff($info['stid']);
        $info['sorderNo']    = $info['sourceTable'] ? query($info['sourceTable'], " id = '{$info['sourceId']}' ")['orderNo'] : '';
        $info['warehouseId'] = query('warehouse', "id = '$info[warehouseId]'")['name'];
        $info['targetId']    = inStockOtherClass::getCompanyName($info['targetId']);
        $info['qr']          = 'source=' . self::page . '&id=' . $info['id'];
        $info['orderDate']   = date('Y/m/d', strtotime($info['orderDate']) ?: strtotime($info['time']));
        $detail              = find(['table' => self::tableMx, 'where' => "orderId = '$info[id]' order by list asc"])['array'];
        $items               = [];
        $x                   = 1;
        $totalNum            = 0;
        foreach ($detail as $array) {
            $material    = query('material', "id = '$array[materialId]'");
            $warehouse   = query('warehouse', "id = '$array[warehouseId]'");
            $items[]     = [
                'no'              => $x,
                'materialCode'    => $material['code'],
                'materialName'    => $material['name'],
                'warehouse'       => $warehouse['name'],
                'model'           => $material['model'],
                'unit'            => $material['unit'],
                'num'             => self::lostZero($array['num'], 'numPrecision'),
                'text'            => $array['text'],
            ];
            $x++;
            $totalNum += floatval($array['num']);
        }
        $append         = [
            'no'  => L('inStock.print.total'),
            'num' => $totalNum,
        ];
        $items[]        = $append;
        $info['detail'] = $items;
        if ($isReturn) {
            return (new printTemplateClass())->start(self::page, $info);
        } else {
            return $info;
        }
    }
    /**
     * 导出模板字段初始化
     * @return array[]
     */
    public function exportFieldInit($classify=''): array
    {
        return match ($classify) {
            default=>  [
                [
                    'columnName'=>'仓库',
                    'aliasName'=>'仓库',
                ],
                [
                    'columnName'=>'业务类型',
                    'aliasName'=>'业务类型',
                ],
                [
                    'columnName'=>'源单编号',
                    'aliasName'=>'源单编号',
                ],
                [
                    'columnName'=>'往来单位',
                    'aliasName'=>'往来单位',
                ],
                [
                    'columnName'=>'源单日期',
                    'aliasName'=>'源单日期',
                ],
                [
                    'columnName'=>'入库单号',
                    'aliasName'=>'入库单号',
                ],
                [
                    'columnName'=>'物料编码',
                    'aliasName'=>'物料编码',
                ],
                [
                    'columnName'=>'物料名称',
                    'aliasName'=>'物料名称',
                ],
                [
                    'columnName'=>'规格型号',
                    'aliasName'=>'规格型号',
                ],
                [
                    'columnName'=>'单位',
                    'aliasName'=>'单位',
                ],
                [
                    'columnName'=>'单据数量',
                    'aliasName'=>'单据数量',
                ],
                [
                    'columnName'=>'已入库数量',
                    'aliasName'=>'已入库数量',
                ],
                [
                    'columnName'=>'批次明细',
                    'aliasName'=>'批次明细',
                ],
                [
                    'columnName'=>'剩余未入库数量',
                    'aliasName'=>'剩余未入库数量',
                ],
            ]
        };
    }
    /**
     * Desc : 质检后改变待出入库单状态 及合格数量
     * User : you name
     * Date : 2024-06-27 19:00
     * @param array $info
     * @param bool $state 状态 true通过质检 false撤回质检
     * @return mixed
     * @throws \Exception
     */
    public static function qualityInventory(array $info, $state = true): mixed
    {
        $info = query("quality_order"," id = '".$info['id']."' "); // 数据有变动，需要重新查询
        $inventory_detail = query("inventory_detail"," coid = '" . self::$coid . "' and sourceId = '".$info['sourceMxId']."' and materialId = '".$info['materialId']."' ");
        if($state){
            $state = '已质检';
            $pass_num = floatval($inventory_detail['pass_num']) + floatval($info['passNum']);
        }else{
            $state = '待质检';
            $pass_num = floatval($inventory_detail['pass_num']) - floatval($info['passNum']);
        }
        $quality = 2;
        if($pass_num <= 0){
            $quality = 1;
        }

        //判断此订单所有批次是否都检验完了，如果检验完成，则修改待出入库单质检状态为已质检
        if (static::total(array('table' => 'quality_order', "where" => "state = '待质检' and sourceId ='$info[sourceId]' and coid = '" . self::$coid . "'")) == 0) {
            update(array(
                'table' => 'inventory',
                'field' => ['workFlow' => $state],
                'where' => " id = '$inventory_detail[orderId]' "
            ));
        }
        if($inventory_detail['id']){
            update(array(
                'table' => 'inventory_detail',
                'field' => [
                    'quality' => $quality,
                    'pass_num' => $pass_num,
                ],
                'where' => " id = '$inventory_detail[id]' "
            ));
        }
        return true;
    }
}
